package znet

import (
	"bytes"
	"encoding/binary"
	"errors"
	"zinx/Zinx/utils"
	"zinx/Zinx/ziface"
)

// IDataPack接口实现, 定义一个DataPack数据包模块. 数据包方法类实例, 不需要成员
type DataPack struct{}

// 初始化数据包
func NewDataPack() *DataPack {
	return &DataPack{}
}

// 获取数据包头长度
func (dp *DataPack) GetHeadLen() uint32 {
	// 即DataLen uint32(4byte)+ID uint32(4byte)=8byte
	return 8
}

// 封包(压缩数据)
func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
	// 创建Buffer缓存数据
	dataBuff := bytes.NewBuffer([]byte{})
	// 将DataLen写入Buffer
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetDataLen()); err != nil {
		return nil, err
	}
	// 将ID写入Buffer
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetID()); err != nil {
		return nil, err
	}
	// 将Data写入Buffer
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetData()); err != nil {
		return nil, err
	}
	return dataBuff.Bytes(), nil
}

// 拆包(解压数据)
func (dp *DataPack) Unpack(datapack []byte) (ziface.IMessage, error) {
	// 创建Reader读取数据包数据
	dataBuff := bytes.NewReader(datapack)
	// 创建数据实例
	msg := &Message{}
	// 读DataLen, 存入数据实例
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.DataLen); err != nil {
		return nil, err
	}
	// 读ID, 存入数据实例
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.ID); err != nil {
		return nil, err
	}
	// 判断DataLen长度是否符合要求
	if utils.Global.MaxPackageSize > 0 && msg.DataLen > utils.Global.MaxPackageSize {
		return nil, errors.New("[Message Data]too large")
	}
	// 读取包头即可，通过包头的DataLen再从连接中读取数据
	return msg, nil
}
